#include "searchbar.h"
#include "ui_searchbar.h"

#define ROLE_LINEFROM    Qt::UserRole + 1
#define ROLE_IDXFROM     Qt::UserRole + 2
#define ROLE_LINETO      Qt::UserRole + 3
#define ROLE_IDXTO       Qt::UserRole + 4

SearchBar::SearchBar(QWidget *parent) :
    SideBarBase(parent),
    ui(new Ui::SearchBar)
{
    ui->setupUi(this);
    setObjectName("SearchBar");
    setupBar(tr("Search and Replace"), false);

    connect(ui->tbFindNext, SIGNAL(pressed()), this, SIGNAL(next()));
    connect(ui->tbFindPrev, SIGNAL(pressed()), this, SIGNAL(prev()));
    connect(ui->tbSearchAll, SIGNAL(pressed()), this, SIGNAL(searchAll()));
    connect(ui->tbReplace, SIGNAL(pressed()), this, SIGNAL(replace()));
    connect(ui->tbReplaceAll, SIGNAL(pressed()), this, SIGNAL(replaceAll()));

    domainMenu = new QMenu(this);
    actCurrent = domainMenu->addAction(tr("Whole Document"));
    actCurrent->setData(SD_FILE);
    actToCursor = domainMenu->addAction(tr("From the Beginning to Cursor"));
    actToCursor->setData(SD_TO_CURSOR);
    actFromCursor = domainMenu->addAction(tr("From Cursor to the End"));
    actFromCursor->setData(SD_FROM_CURSOR);
    actSelection = domainMenu->addAction(tr("Current Selection"));
    actSelection->setData(SD_SELECTION);
    actFiles = domainMenu->addAction(tr("Open Documents"));
    actFiles->setData(SD_OPENFILES);

    ui->tbDomain->setMenu(domainMenu);
    connect(domainMenu, SIGNAL(triggered(QAction*)), this, SLOT(domainChanged(QAction*)));

    ui->tbWrap->setChecked(true);

//    ui->twResults->header()->setResizeMode(0, QHeaderView::ResizeToContents);
//    ui->twResults->header()->setResizeMode(1, QHeaderView::Stretch);
    ui->twResults->setTextElideMode(Qt::ElideLeft);

    domainChanged(actCurrent);
    on_leFind_textChanged("");
}

SearchBar::~SearchBar()
{
    delete ui;
}

void SearchBar::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type())
    {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void SearchBar::setVisible ( bool visible )
{
  if (visible)
  {
    ui->leFind->selectAll();
    ui->leFind->setFocus();
  }

  QWidget::setVisible(visible);
}

void SearchBar::setFileSearch()
{
  domainChanged(actFiles);
}

void SearchBar::setSearchText(const QString &text)
{
  clearMessage();

  // check domain
  if (text.isEmpty()) {
    if (domainMenu->defaultAction() == actSelection)
      domainChanged(actFromCursor);
  } else {
    if (text.contains("\n"))  // multiline
    {
      domainChanged(actSelection);
      //ui->leFind->setText("");
      myData.text += "."; // change text to update search
    } else {
      if (domainMenu->defaultAction() == actSelection)
        domainChanged(actCurrent);
      ui->leFind->setText(text);
    }
  }

  ui->leFind->selectAll();
  ui->leFind->setFocus();
}

QString SearchBar::searchText() const
{
  return ui->leFind->text();
}

const SearchData& SearchBar::searchData()
{
  QString newText = ui->leFind->text();
  myData.newsearch = (newText != myData.text);
  myData.text = newText;

  myData.replaceText = ui->leReplace->text();

  myData.cs = ui->tbCase->isChecked();
  myData.re = ui->tbRegExp->isChecked();
  myData.wo = ui->tbWords->isChecked();
  myData.wrap = ui->tbWrap->isChecked();

  //qDebug() << "searchData(): domainMenu->activeAction(): " << domainMenu->defaultAction();
  SearchDomain newDom = (SearchDomain) domainMenu->defaultAction()->data().toInt();
  if (newDom != myData.dom) myData.newsearch = true;
  myData.dom = newDom;

  return myData;
}

void SearchBar::domainChanged(QAction *act)
{
  ui->tbDomain->setText(act->text());
  domainMenu->setDefaultAction(act);
  //qDebug() << "domainMenu->activeAction(): " << domainMenu->defaultAction();
}

void SearchBar::on_leFind_textChanged(const QString& text)
{
  bool on = text.length();
  ui->tbFindNext->setEnabled(on);
  ui->tbFindPrev->setEnabled(on);
  ui->tbSearchAll->setEnabled(on);
  ui->tbReplace->setEnabled(on);
  ui->tbReplaceAll->setEnabled(on);

  emit textChanged();
}

void SearchBar::showMessage(const QString &text)
{
  ui->resultLabel->setText(text);
  ui->leFind->setStyleSheet("");
}

void SearchBar::showMessageNotFound(const QString &text)
{
  ui->resultLabel->setText(text);
  ui->leFind->setStyleSheet("background-color: #ff9999;");
}

void SearchBar::clearMessage()
{
  ui->resultLabel->clear();
  ui->leFind->setStyleSheet("");
}

void SearchBar::clearResults()
{
  ui->twResults->clear();
}

void SearchBar::searchStarted()
{
  ui->twResults->setUpdatesEnabled(false);
  ui->twResults->header()->setResizeMode(0, QHeaderView::Fixed);
  ui->twResults->header()->setResizeMode(1, QHeaderView::Fixed);
}

void SearchBar::searchFinished()
{
  ui->twResults->header()->setResizeMode(0, QHeaderView::ResizeToContents);
  ui->twResults->header()->setResizeMode(1, QHeaderView::Stretch);
  ui->twResults->setUpdatesEnabled(true);
}

void SearchBar::addResult(const QString &file, const QString &text, const SearchResult &res)
{
  QTreeWidgetItem *item = new QTreeWidgetItem(ui->twResults);
  //item->setText(0, QString("[%1:%2]").arg(res.lineFrom+1).arg(res.indexFrom+1));
  item->setText(0, QString("%1").arg(res.lineFrom+1));
  item->setData(0, ROLE_IDXFROM, res.indexFrom);
  item->setData(0, ROLE_IDXTO, res.indexTo);
  item->setData(0, ROLE_LINEFROM, res.lineFrom);
  item->setData(0, ROLE_LINETO, res.lineTo);
  item->setBackgroundColor(0, Qt::lightGray);
  QString line(text);
  line.remove("\n");
  line.remove("\r");
  item->setText(1, line);
  item->setText(2, file);
  item->setBackgroundColor(2, Qt::lightGray);
  ui->twResults->addTopLevelItem(item);

  ui->twResults->setUpdatesEnabled(true);
}

void SearchBar::on_twResults_activated(const QModelIndex & index)
{
  if (!index.isValid())
    return;

  QTreeWidgetItem *item = ui->twResults->topLevelItem(index.row());
  SearchResult res;
  res.lineFrom = item->data(0, ROLE_LINEFROM).toInt();
  res.indexFrom = item->data(0, ROLE_IDXFROM).toInt();
  res.lineTo = item->data(0, ROLE_LINETO).toInt();
  res.indexTo = item->data(0, ROLE_IDXTO).toInt();
  emit resultClicked(item->text(2), item->text(1), res);
}

